package controller;

import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import utils.Utils;
import utils.XmlParser;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.widget.TextView;
import app.cloudstringers.Home;
import app.cloudstringers.R;
import define.API;
import define.DefaultValue;
import define.Key;
import define.SharedPreference;

public class LoginAsync extends AsyncTask<String, Void, Boolean> {

	/**
	 * String section
	 */
	private static final String TAG = LoginAsync.class.getSimpleName();

	private static final String KEY_BUY_SELL = "BUYSELL";
	private static final String KEY_FIRMWARE_VERSION = "FIRMWARE_VERSION";
	private static final String KEY_GLOBAL_ID = "GLOBAL_ID";
	private static final String KEY_USER_ID = "USER_ID";

	private String FIRMWARE_VERSION = null, SELL = null;

	/**
	 * View section
	 */
	private AlertDialog.Builder mAdLoginFail;
	private AlertDialog.Builder mAdSucceedLogin;

	/**
	 * The others section
	 */
	private Utils connectivity;
	private Context context;
	private SharedPreferences.Editor mSpEditor;
	private SharedPreferences mSpSettings;
	private Thread mThreadTranslation = new Thread(new Runnable() {

		@Override
		public void run() {
			Intent intent = new Intent(context, Home.class);
			Activity activity = (Activity) context;
			activity.finish();
			context.startActivity(intent);
		}
	});
	public static Timer mTimerNextPageTranslation;
	private TimerTask mTmTranslation = new TimerTask() {
		@Override
		public void run() {
			mThreadTranslation.start();
		}
	};
	private XmlParser mXMLParser;

	/**
	 * LoginAsync
	 * @param context
	 */
	public LoginAsync(Context context) {
		this.context = context;

		connectivity = new Utils(context);

		// Get data from shared preferences
		mSpSettings = context.getSharedPreferences(SharedPreference.PREFS,
				Context.MODE_PRIVATE);
		mSpEditor = mSpSettings.edit();
	}

	@Override
	protected Boolean doInBackground(String... params) {
		return getData(params);
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();

		connectivity.showProgressDialog();

		initialAlertDialog();
	}

	@Override
	protected void onPostExecute(Boolean result) {
		super.onPostExecute(result);

		if (!result) {
			mAdLoginFail.show();
		} else {
			// Show succeed login
			mAdSucceedLogin.show();

			// New runnable after 7 seconds
			mTimerNextPageTranslation = new Timer();
			mTimerNextPageTranslation.schedule(mTmTranslation,
					define.Timer.TIMER_REFRESH_IN_STATUS_TAB);
		}

		connectivity.hideProgressDialog();
	}

	/**
	 * Initial methods
	 */
	private void initialAlertDialog() {
		mAdLoginFail = new AlertDialog.Builder(context);
		mAdLoginFail.setTitle(context.getString(R.string.title_incorrect_user));
		mAdLoginFail.setIcon(R.drawable.ibtn_error_normal);
		mAdLoginFail.setCancelable(false);
		mAdLoginFail.setMessage(context
				.getString(R.string.content_wrong_username_password));
		mAdLoginFail.setPositiveButton(R.string.try_again,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog9, int whichButton) {
						// Set text is null
						TextView mTvPassword = (TextView) ((Activity) context)
								.findViewById(R.id.et_password);
						mTvPassword.setText("");
					}
				});
		mAdLoginFail.setNegativeButton(R.string.quit,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog9, int whichButton) {
						android.os.Process.killProcess(android.os.Process
								.myPid());
					}
				});

		mAdSucceedLogin = new AlertDialog.Builder(context);
		mAdSucceedLogin.setTitle(context.getString(R.string.title_login));
		mAdSucceedLogin.setMessage(context
				.getString(R.string.content_login_success));
		mAdSucceedLogin.setPositiveButton(R.string.ok,
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog9, int whichButton) {
						mThreadTranslation.start();
					}
				});
	}

	/**
	 * Basic methods
	 */

	private boolean getData(String[] params) {
		HttpPost mHttpPost = new HttpPost(API.USER_LOGIN);
		List<NameValuePair> mListValues = new ArrayList<NameValuePair>(2);

		mListValues.add(new BasicNameValuePair(Key.KEY_USER_NAME, params[1]));
		mListValues.add(new BasicNameValuePair(Key.KEY_PASWORD, params[2]));
		mListValues.add(new BasicNameValuePair(Key.KEY_DEVICE_TOKEN, params[3]));
		mListValues.add(new BasicNameValuePair(Key.KEY_DEVICE_OS, params[4]));
		
		try {
			mHttpPost.setEntity(new UrlEncodedFormEntity(mListValues));
			HttpParams mHttpParams = new BasicHttpParams();

			int TIMEOUT_CONNECTION = 30000;
			int TIMEOUT_SOCKET = 30000;

			HttpConnectionParams.setConnectionTimeout(mHttpParams,
					TIMEOUT_CONNECTION);
			HttpConnectionParams.setSoTimeout(mHttpParams, TIMEOUT_SOCKET);

			HttpClient mHttpclient = new DefaultHttpClient(mHttpParams);
			HttpResponse mHttpResponse;

			mHttpResponse = mHttpclient.execute(mHttpPost);

			HttpEntity mHttpEntity = mHttpResponse.getEntity();

			String XML = EntityUtils.toString(mHttpEntity);

//			Log.i(TAG, XML);

			mXMLParser = new XmlParser();
			Document mDocument = mXMLParser.getDomElement(XML);

			NodeList mNdNodeList = mDocument.getElementsByTagName(KEY_USER_ID);
			for (int i = 0; i < mNdNodeList.getLength(); i++) {
				if (mNdNodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
					Element element = (Element) mNdNodeList.item(i);

					// get child value
					FIRMWARE_VERSION = mXMLParser.getValue(element,
							KEY_FIRMWARE_VERSION);
					params[0] = mXMLParser.getValue(element, KEY_GLOBAL_ID);
					SELL = mXMLParser.getValue(element, KEY_BUY_SELL);
				}
			}

			if (params[0].equals(DefaultValue.DEFAULT_GLOBAL_ID)) {
				return false;
			} else {
				// Save into Shared Preference
				mSpEditor.putString(
						SharedPreference.PREFS_KEY_FIRMWARE_VERSION,
						FIRMWARE_VERSION);
				mSpEditor.putString(SharedPreference.PREFS_KEY_GLOBAL_ID,
						params[0]);
				mSpEditor.putString(SharedPreference.PREFS_KEY_LOGIN_NAME,
						params[1]);
				mSpEditor.putString(SharedPreference.PREFS_KEY_PASSWORD,
						params[2]);
				mSpEditor.putString(SharedPreference.PREFS_KEY_SELL, SELL);
				mSpEditor.commit();

				return true;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ConnectTimeoutException e) {
			e.printStackTrace();
			return false;
		} catch (SocketException e) {
			e.printStackTrace();
			return false;
		} catch (SocketTimeoutException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
}
